def header(package_name: str, classname: str) -> str:
    ret = f"package {package_name};\r\n\r\n"
    ret += '''import org.squirrelframework.foundation.fsm.annotation.*;
import org.squirrelframework.foundation.fsm.impl.AbstractUntypedStateMachine;\r\n'''
    
    ret += f'import static {package_name}.{classname}.*;\r\n\r\n'

    return ret


def states_header() -> str:
    return '@States({\r\n'


def states_repr(machine, parent_state=None) -> str:
    ret = ""

    for state in machine.states:
        if parent_state is None:
            ret += (' ' * 8 + f'@State(name = S_{state.name}),\r\n')
        else:
            ret += (' ' * 8 + f'@State(name = S_{state.name}, parent = S_{parent_state}),\r\n')

        if state.sub_machine:
            ret += states_repr(state.sub_machine, state.name)

    return ret



def states_footer() -> str:
    return "})\r\n"


def transitions_header() -> str:
    return "@Transitions({\r\n"


def transitions_repr(machine) -> str:
    ret = ""

    for t in machine.transitions:
        ret += (' ' * 8 + f'@Transit(from = S_{t.from_state}, to = S_{t.to_state}, on = E_{t.trigger}, callMethod = "{t.transition_method_name()}"),\r\n')

    for s in machine.states:
        if not (s.sub_machine is None):
            ret += transitions_repr(s.sub_machine)

    return ret


def transitions_footer() -> str:
    return "})\r\n"


def context_annotation() -> str:
    return "@StateMachineParameters(stateType = String.class, eventType = String.class, contextType = Object.class)\r\n"


def class_declaration_start(classname: str) -> str:
    return f'public class {classname} extends AbstractUntypedStateMachine {{\r\n\r\n'


def states_declaration(state_names) -> str:
    ret = ''
    for state in state_names:
        ret += f'    public static final String S_{state} = "{state}";\r\n'

    return ret


def events_declaration(event_names) -> str:
    ret = ''
    for trigger in event_names:
        ret += f'    public static final String E_{trigger} = "{trigger}";\r\n'

    return ret


def transition_methods_repr(methods) -> str:
    ret = ''
    for method in methods:
        ret += f'    private void {method}(String from, String to, String event, String context) {{}}\r\n\r\n'

    return ret

def class_declaration_end():
    return '}\r\n'

